package org.ko.core.dao.jpa;

import java.io.Serializable;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.LockModeType;

import org.ko.core.domain.support.P;
import org.ko.core.websupport.page.Paginable;


/**
 * Dao - 基类,提供对实体常用如CRUD操作,编写新的Dao只需要声明接口,并继承此接口
 * 实现新编写接口需要继承BaseDaoRawImpl
 * 如   public class UserDaoImpl extends BaseDaoRawImpl<User, Long>implements UserDao
 * 
 * <T, ID extends Serializable>,T 指的是这个Dao绑定哪个实体,ID为实体主键
 * @author ByTheWay
 * @version 1.0.0
 */
public interface BaseDao<T, ID extends Serializable> {

	EntityManager getEm();
	/**
	 * 查找实体对象
	 * 
	 * @param id
	 *            ID
	 * @return 实体对象，若不存在则返回null
	 */
	T find(ID id);
	
	/**
	 * 查询单个结果
	 * @param <X>
	 * @param hql
	 * @param params
	 * @return
	 */
	<X> X getOne(String hql,P ...params);
	/**
	 * 根据条件查找实体对象,如果有多个则只返回第一个结果
	 * @param filters
	 * @return
	 */
	/**
	 * 查找实体对象集合
	 * 
	 * @param first
	 *            起始记录
	 * @param count
	 *            数量
	 * @param filters
	 *            筛选
	 * @param orders
	 *            排序
	 * @return 实体对象集合
	 */
	public <X> List<X> findList(String hql, P... params); 
	public <X> List<X> findList(P... params); 
	public <X> List<X> findin(ID... ids); 

	/**
	 * 查找实体对象分页
	 * 
	 * @param pageable
	 *            分页信息
	 * @return 实体对象分页
	 */
	Paginable findPage(String hql, P ...params); 
	Paginable findPage(P ...params); 

	/**
	 * 查询实体对象数量
	 * 
	 * @param filters
	 *            筛选
	 * @return 实体对象数量
	 */
	long count(String hql,P ...params);

	/**
	 * 持久化实体对象
	 * 
	 * @param entity
	 *            实体对象
	 */
	void save(T entity);

	/**
	 * 合并实体对象
	 * 
	 * @param entity
	 *            实体对象
	 * @return 实体对象
	 */
	T update(T entity);

	/**
	 * 更新实例
	 * @param hql
	 * @param params
	 * @return
	 */
	int update(String hql,P ...params);
	/**
	 * 移除实体对象
	 * 
	 * @param entity
	 *            实体对象
	 */
	void delete(T entity);
	void delete(ID pk);

	/**
	 * 刷新实体对象
	 * 
	 * @param entity
	 *            实体对象
	 */
	void refresh(T entity);

	/**
	 * 获取实体对象ID
	 * 
	 * @param entity
	 *            实体对象
	 * @return 实体对象ID
	 */
	ID getIdentifier(T entity);

	/**
	 * 判断是否为托管状态
	 * 
	 * @param entity
	 *            实体对象
	 * @return 是否为托管状态
	 */
	boolean isManaged(T entity);

	/**
	 * 设置为游离状态
	 * 
	 * @param entity
	 *            实体对象
	 */
	void detach(T entity);

	/**
	 * 锁定实体对象
	 * 
	 * @param entity
	 *            实体对象
	 * @param lockModeType
	 *            锁定方式
	 */
	void lock(T entity, LockModeType lockModeType);

	/**
	 * 清除缓存
	 */
	void clear();

	/**
	 * 同步数据
	 */
	void flush();

}